package cloud.code.serverOne.web.config;

import cloud.code.serverOne.web.dto.UserLoginSessionDto;
import cloud.code.serverOne.web.entity.TUserEntity;
import cloud.code.serverOne.web.service.TUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.HashSet;
import java.util.Set;

@Component
public class ShiroRealm extends AuthorizingRealm {

    @Resource
    private TUserService tUserService;

    /**
     * 授权模块，获取用户角色和权限
     *
     * @param principal principal
     * @return AuthorizationInfo 权限信息
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principal) {
        UserLoginSessionDto user = (UserLoginSessionDto) SecurityUtils.getSubject().getPrincipal();

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();

        // 获取用户角色集
        Set<String> roleSet = user.getRoles();
        simpleAuthorizationInfo.setRoles(roleSet);

        // 获取用户权限集
        Set<String> permissionSet = user.getPermissions();
        simpleAuthorizationInfo.setStringPermissions(permissionSet);
        return simpleAuthorizationInfo;
    }

    /**
     * 用户认证
     *
     * @param token AuthenticationToken 身份认证 token
     * @return AuthenticationInfo 身份认证信息
     * @throws AuthenticationException 认证相关异常
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) throws AuthenticationException {
        // 获取用户输入的用户名和密码
        String loginName = (String) token.getPrincipal();
        String password = new String((char[]) token.getCredentials());

        // 通过用户名到数据库查询用户信息
        QueryWrapper<TUserEntity> queryWrapper = new QueryWrapper<>();
        queryWrapper.lambda().eq(TUserEntity::getLoginName, loginName);
        TUserEntity user = tUserService.getOne(queryWrapper);


        if (user == null)
            throw new UnknownAccountException("账号未注册！");
        if (!StringUtils.equals(password, user.getPassword()))
            throw new IncorrectCredentialsException("用户名或密码错误！");

        UserLoginSessionDto userLoginSessionDto = new UserLoginSessionDto();
        userLoginSessionDto.setUserId(user.getUserId());
        userLoginSessionDto.setUsername(user.getUsername());
        userLoginSessionDto.setPassword(user.getPassword());
        userLoginSessionDto.setLoginName(user.getLoginName());

        //获取用户角色集合
        Set<String> r = new HashSet<>();
        r.add("aaa");
        r.add("bbb");
        userLoginSessionDto.setRoles(r);
        Set<String> p = new HashSet<>();
        p.add("ccc");
        p.add("ddd");
        userLoginSessionDto.setPermissions(p);
        return new SimpleAuthenticationInfo(userLoginSessionDto, userLoginSessionDto.getPassword(), getName());
    }

    /**
     * 清除当前用户权限缓存
     * 使用方法：在需要清除用户权限的地方注入 ShiroRealm,
     * 然后调用其 clearCache方法。
     */
    public void clearCache() {
        PrincipalCollection principals = SecurityUtils.getSubject().getPrincipals();
        super.clearCache(principals);
    }
}
